import tkinter as tk
import random

MAXSIZE = 10

window = tk.Tk()
window.title("磁盘调度算法_陈冠宇_3122010025")
window.maxsize(520, 390)
window.minsize(520, 390)

def FCFS(start, List):
    MAXSIZE = len(List)  # Python中的列表大小是动态的，所以我们从列表中获取它  
    order = [0] * MAXSIZE  # 创建一个与list_values相同大小的列表，并用0填充  
    sum_distance = 0  
     
    result1_1 = tk.Label(window, text="\nYou are using FCFS algorithm.\nHere is the service order:\n")  
    result1_1.place(x=150, y=140, width=200, height=50) 

    result1_2 = tk.Label(window, text=List)  
    result1_2.place(x=130, y=180, width=250, height=50) 
  
    order[0] = start  
    for j in range(1, MAXSIZE):  
        order[j] = List[j-1]  # 注意这里的逻辑在Python中可能不是最直观的，但根据C代码重写  
  
    for k in range(MAXSIZE):  
        distance = abs(order[k]-List[k])  
        print(distance, end="")  
        if k != MAXSIZE - 1:  
            print("+", end="")  
        sum_distance += distance  
  
    result1_3 = tk.Label(window, text="\nThe total distance is:{}".format(sum_distance))  
    result1_3.place(x=120, y=220, width=250, height=30) 
  
    average_distance = sum_distance / MAXSIZE  
    result1_4 = tk.Label(window, text="\nThe average distance is: {:.2f}\n".format(average_distance))  
    result1_4.place(x=120, y=250, width=250, height=30) 


def SSTF(start, List):  
    MAXSIZE = len(List)  
    temp = List[:]  # 复制列表  
    ord_list = []  
    staff = 0  
    dif = 200  
    now = start  
    sum_distance = 0  
  
    for _ in range(MAXSIZE):  
        min_dif = float('inf')  # 初始化为无穷大  
        for j in range(MAXSIZE):  
            if temp[j] != 2000 and min_dif > abs(now - temp[j]):  
                min_dif = abs(now - temp[j])  
                staff = j  
  
        now = temp[staff]  
        ord_list.append(staff)  
        temp[staff] = 2000  # 标记为已访问  
  
    result2_1 = tk.Label(window, text="\nYou are using SSTF algorithm.\nHere is the service order:\n")  
    result2_1.place(x=150, y=140, width=200, height=50) 

    temp[0] = List[ord_list[0]]
    prev_request = start  
    for i in range(1, MAXSIZE):  
        temp[i] = List[ord_list[i]]
        print(List[ord_list[i]])  
        prev_request = List[ord_list[i-1]]  

    result2_2 = tk.Label(window, text=temp)  
    result2_2.place(x=130, y=180, width=250, height=50) 
    prev_request = start
    total_distance_str = ""  
    for k in range(MAXSIZE):  
        distance = abs(prev_request - List[ord_list[k]])  
        total_distance_str += str(distance)  
        if k != MAXSIZE - 1:  
            total_distance_str += "+"  
        sum_distance += distance  
        prev_request = List[ord_list[k]]  
  
    result2_3 = tk.Label(window, text="\nThe total distance is:{}".format(sum_distance))  
    result2_3.place(x=120, y=220, width=250, height=30) 
    average_distance = sum_distance / MAXSIZE  
    result2_4 = tk.Label(window, text="\nThe average distance is: {:.2f}\n".format(average_distance))  
    result2_4.place(x=120, y=250, width=250, height=30) 

def SCAN(start, List): 
    temp = List.copy()  # 复制列表，以便不改变原始请求  
    ord_list = [-1] * MAXSIZE  # 初始化服务顺序列表  
    now = start  
    sum_distance = 0  
      
    # 向上扫描  
    for i in range(MAXSIZE):  
        staff = -1  
        dif = float('inf')  
        for j in range(MAXSIZE):  
            if dif > temp[j] - now and temp[j] > now and temp[j] != 2000:  # 排除已经服务过的请求  
                dif = temp[j] - now  
                staff = j  
        if staff != -1:  
            now = temp[staff]  
            temp[staff] = 2000  
            ord_list[i] = staff  
        else:  
            break  # 没有找到可服务的请求，停止向上扫描  
  
    # 向下扫描（从上次停止的位置开始）  
    t = i  
    for i in range(t, MAXSIZE):  
        staff = -1  
        dif = float('inf')  
        for j in range(MAXSIZE):  
            if dif > now - temp[j] and now > temp[j] and temp[j] != 2000:  # 排除已经服务过的请求  
                dif = now - temp[j]  
                staff = j  
        if staff != -1:  
            now = temp[staff]  
            temp[staff] = 2000  
            ord_list[i] = staff  
  
    result3_1 = tk.Label(window, text="\nYou are using SCAN algorithm.\nHere is the service order:\n")  
    result3_1.place(x=150, y=140, width=200, height=50) 

    for idx in ord_list:  
        if idx != -1:
            print(List[idx])  
    temp[0] = List[ord_list[0]]
    for i in range(1, MAXSIZE):  
        temp[i] = List[ord_list[i]]
    
    result3_2 = tk.Label(window, text=temp)  
    result3_2.place(x=130, y=180, width=250, height=50) 
    # 计算总距离和平均距离  
    prev_position = start  
    for idx in ord_list:  
        if idx != -1:  
            sum_distance += abs(prev_position - List[idx])  
            prev_position = List[idx]  

    result3_3 = tk.Label(window, text="\nThe total distance is:{}".format(sum_distance))  
    result3_3.place(x=120, y=220, width=250, height=30) 

    average_distance = sum_distance / MAXSIZE  # 排除-1（未服务请求）  
    result3_4 = tk.Label(window, text="\nThe average distance is: {:.2f}\n".format(average_distance))  
    result3_4.place(x=120, y=250, width=250, height=30) 

def CSCAN(start, List):  
    MAXSIZE = len(List)  
    temp = List.copy()  # 复制列表，以便不改变原始请求  
    temp0 = temp.copy()
    ord = [-1] * MAXSIZE  # 初始化服务顺序列表  
    now = start
    sum = 0
    for i in range(MAXSIZE):
        staff = 10
        dif = 200
        for j in range(MAXSIZE):
            if dif > temp[j] - now:
                if temp[j] >= now:
                    dif = temp[j] - now
                    staff = j
        if staff != 10:
            now = temp[staff]
            temp[staff] = 2000
            ord[i] = staff
        else:
            staff = i
            break
    t = staff
    now = 0
    for i in range(t, MAXSIZE):
        staff = 10
        dif = 200
        for j in range(MAXSIZE):
            if dif > temp[j] - now and temp[j] >= now:
                dif = temp[j] - now
                staff = j
        if staff != 10:
            now = temp[staff]
            temp[staff] = 2000
            ord[i] = staff
        else:
            staff = i
            break
    result4_1 = tk.Label(window, text="\nYou are using CSCAN algorithm.\nHere is the service order:\n")  
    result4_1.place(x=150, y=140, width=200, height=50) 
    temp[0] = start
    temp0[0] = List[ord[0]]
    for i in range(1, MAXSIZE):
        temp[i] = List[ord[i-1]]
        temp0[i] = List[ord[i]]
    print(temp0)
    result4_2 = tk.Label(window, text=temp0)  
    result4_2.place(x=130, y=180, width=250, height=50) 
    for k in range(MAXSIZE):
        print(abs(temp[k] - List[ord[k]]))
        if k != 9:
            print("+")
        sum += abs(temp[k] - List[ord[k]])
    print("=", sum)
    result4_3 = tk.Label(window, text="\nThe total distance is:{}".format(sum))  
    result4_3.place(x=120, y=220, width=250, height=30) 
    average = sum/MAXSIZE
    result4_4 = tk.Label(window, text="\nThe average distance is: {:.2f}\n".format(average))  
    result4_4.place(x=120, y=250, width=250, height=30) 
        
user_input = None
 
def get_user_input():  
    global user_input  # 声明使用全局变量  
    user_input = entry.get()  # 更新全局变量  

List = [random.randint(0, 199) for _ in range(10)]

displayWelcome = tk.Label(window, text="Thanks for using Disk Scheduling Algorithm\nYou've been given a set of Track Number:")  
displayWelcome.place(x=120, y=5, width=280, height=50) 

displayList = tk.Label(window, text=List)  
displayList.place(x=130, y=50, width=250, height=40) 
  
# 创建一个Entry控件  
entry = tk.Entry(window)
entry.place(x=190, y=120)

displayStart = tk.Label(window, text="You start with number(0~199):")  
displayStart.place(x=130, y=80, width=250, height=40) 

def press_The_Rest_of_The_Button():
    get_user_input()
    input = int(user_input)
    button1 = tk.Button(window, text="FCFS", command=lambda: FCFS(input, List))
    button2 = tk.Button(window, text="SSTF", command=lambda: SSTF(input, List))
    button3 = tk.Button(window, text="SCAN", command=lambda: SCAN(input, List))
    button4 = tk.Button(window, text="CSCAN", command=lambda: CSCAN(input, List))
    button1.place(x=40, y=300, width=80, height=40)
    button2.place(x=160, y=300, width=80, height=40)
    button3.place(x=280, y=300, width=80, height=40)
    button4.place(x=400, y=300, width=80, height=40)

button0 = tk.Button(window, text="SUBMIT", command=press_The_Rest_of_The_Button)
button0.place(x=340, y=120, width=60, height=20)

window.mainloop()